#pragma once
#include "Mesh.h"
#include "Shader.h"

namespace Rendering {

class Renderer;

class Element
{
public:
	Element();

	void SetMesh(Mesh* mesh) { m_mesh = mesh; }
	Mesh* GetMesh() { return m_mesh; }

	Shader* GetShader() { return m_shader; };
	void SetShader(Shader* shader) { m_shader = shader; };

	virtual void Render(_In_ Renderer* renderer);

	/// <summary>Renders the object.</summary>
	/// <param name="renderer">The renderer to render this object.</param>
	/// <param name="primitiveConstantBuffer">The constant buffer to the shaders.</param>
	/// <param name="constantBuffer">The value for the constant buffer to the shaders.</param>
template<typename T>
	void Render(_In_ Renderer* renderer, _In_ ID3D11Buffer *primitiveConstantBuffer, T& constantBuffer)
	{
		if (this->Mesh() == nullptr || this->Shader() == nullptr)
			return;

		ID3D11DeviceContext1Ptr context = renderer->Context();
		TRY_POINTER(context);

		context->UpdateSubresource(primitiveConstantBuffer, 0, nullptr, &constantBuffer, 0, 0);
		Render(renderer);
	}

	virtual void Transform(_In_ Renderer* renderer, _In_ DirectX::CXMMATRIX matrix){}

	///<summary>Gets/Sets the position of the object in the viewport.</summary>
	///<value>The position of the object in the viewport.</value>
	DirectX::XMFLOAT3 Position;

	///<summary>Gets the constant buffer for the shader specific for this object.</summary>
	///<value>The constant buffer for the shader specific for this object.</value>		
	ID3D11BufferPtr  ElementConstantBuffer() { return m_elementConstantBuffer; }

protected:
	Mesh*		 m_mesh;
	Shader*		 m_shader;
	ID3D11BufferPtr  m_elementConstantBuffer;
};

}
